/**
 * 
 */
package com.binhthuan.catechist.server.bus;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.binhthuan.catechist.server.QueryObject;
import com.binhthuan.catechist.server.domain.AbstractObject;
import com.binhthuan.catechist.server.domain.Trainee;
import com.binhthuan.catechist.server.util.HibernateUtil;
import com.binhthuan.catechist.shared.constant.Parameter;

/**
 * @author dttgiang
 * 
 */
public class TraineeBUS extends AbstractBUS {

    public TraineeBUS() {
    }

    @SuppressWarnings("unchecked")
    public QueryObject getTraineesByCourse(int classId, int start, int limit) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction transaction = null;
        QueryObject result = new QueryObject();
        List<AbstractObject> records = null;
        try {
            transaction = session.beginTransaction();
            Criteria criteria = session.createCriteria(Trainee.class).createCriteria("doctrineClasses").add(
                    Restrictions.eq("id", classId));

            criteria.setProjection(Projections.rowCount());
            result.setTotalRows(Integer.parseInt(criteria.list().get(0).toString()));

            criteria.setProjection(null);
            criteria.setResultTransformer(Criteria.ROOT_ENTITY);
            if (limit > 0) {
                criteria = criteria.setFirstResult(start).setMaxResults(limit);
            }

            records = new ArrayList<AbstractObject>(criteria.list());

            transaction.commit();
        } catch (HibernateException he) {
            he.printStackTrace();
            transaction.rollback();
        } finally {
            session.close();
        }

        result.setStartRows(start);
        int endRow = start;
        if (records != null) {
            endRow += records.size();
            result.setData(records);
        }

        result.setEndRow(endRow);

        return result;
    }

    public QueryObject getActiveTrainees(int start, int limit) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction transaction = null;
        QueryObject result = new QueryObject();
        List<AbstractObject> records = null;
        try {
            transaction = session.beginTransaction();
            Criteria criteria = session.createCriteria(Trainee.class).add(
                    Restrictions.and(Restrictions.eq(Parameter.ACTIVE, true), Restrictions.or(Restrictions.eq(
                            Parameter.TEMPORARY_DELETE, false), Restrictions.isNull(Parameter.TEMPORARY_DELETE))));

            criteria.setProjection(Projections.rowCount());
            result.setTotalRows(Integer.parseInt(criteria.list().get(0).toString()));

            criteria.setProjection(null);
            criteria.setResultTransformer(Criteria.ROOT_ENTITY);
            if (limit > 0) {
                criteria = criteria.setFirstResult(start).setMaxResults(limit);
            }

            records = new ArrayList<AbstractObject>(criteria.list());

            transaction.commit();
        } catch (HibernateException he) {
            he.printStackTrace();
            transaction.rollback();
        } finally {
            session.close();
        }

        result.setStartRows(start);
        int endRow = start;
        if (records != null) {
            endRow += records.size();
            result.setData(records);
        }

        result.setEndRow(endRow);

        return result;
    }

    public QueryObject getInactiveTrainees(int start, int limit) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction transaction = null;
        QueryObject result = new QueryObject();
        List<AbstractObject> records = null;
        try {
            transaction = session.beginTransaction();
            Criteria criteria = session.createCriteria(Trainee.class).add(
                    Restrictions.and(Restrictions.or(Restrictions.eq(Parameter.ACTIVE, false), Restrictions
                            .isNull(Parameter.ACTIVE)), Restrictions.or(Restrictions.eq(Parameter.TEMPORARY_DELETE,
                            false), Restrictions.isNull(Parameter.TEMPORARY_DELETE))));

            criteria.setProjection(Projections.rowCount());
            result.setTotalRows(Integer.parseInt(criteria.list().get(0).toString()));

            criteria.setProjection(null);
            criteria.setResultTransformer(Criteria.ROOT_ENTITY);
            if (limit > 0) {
                criteria = criteria.setFirstResult(start).setMaxResults(limit);
            }

            records = new ArrayList<AbstractObject>(criteria.list());

            transaction.commit();
        } catch (HibernateException he) {
            he.printStackTrace();
            transaction.rollback();
        } finally {
            session.close();
        }

        result.setStartRows(start);
        int endRow = start;
        if (records != null) {
            endRow += records.size();
            result.setData(records);
        }

        result.setEndRow(endRow);

        return result;
    }

    public QueryObject getTemporaryDeleteTrainees(int start, int limit) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction transaction = null;
        QueryObject result = new QueryObject();
        List<AbstractObject> records = null;
        try {
            transaction = session.beginTransaction();
            Criteria criteria = session.createCriteria(Trainee.class).add(
                    Restrictions.eq(Parameter.TEMPORARY_DELETE, true));

            criteria.setProjection(Projections.rowCount());
            result.setTotalRows(Integer.parseInt(criteria.list().get(0).toString()));

            criteria.setProjection(null);
            criteria.setResultTransformer(Criteria.ROOT_ENTITY);
            if (limit > 0) {
                criteria = criteria.setFirstResult(start).setMaxResults(limit);
            }

            records = new ArrayList<AbstractObject>(criteria.list());

            transaction.commit();
        } catch (HibernateException he) {
            he.printStackTrace();
            transaction.rollback();
        } finally {
            session.close();
        }

        result.setStartRows(start);
        int endRow = start;
        if (records != null) {
            endRow += records.size();
            result.setData(records);
        }

        result.setEndRow(endRow);

        return result;
    }

    public Trainee getTraineeById(Integer id) {
        return get(Trainee.class, id);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.binhthuan.catechist.server.bus.AbstractBUS#save(com.binhthuan.catechist
     * .server.domain.AbstractObject)
     */
    public boolean save(Trainee object) {
        object.setLowerCaseName(object.getFullName().toLowerCase());
        return super.save(object);
    }
}
